﻿using System;
using System.Collections.Generic;
using MiniJSON;

namespace FacePP.Recognition.Identify
{
    /// <summary>
    /// 对于一个待查询的Face列表（或者对于给定的Image中所有的Face），在一个Group中查询最相似的Person。
    /// </summary>
    public interface IFace_identify
    {
        /// <summary>
        /// 对于一个待查询的Face列表（或者对于给定的Image中所有的Face），在一个Group中查询最相似的Person。
        /// </summary>
        /// <param name="group_id">识别候选人组成的Group</param>
        /// <param name="url">待识别图片的URL</param>
        /// <param name="mode">检测模式可以是normal(默认) 或者 oneface 。在oneface模式中，检测器仅找出图片中最大的一张脸。仅当给出了url或img时，本选项有效。</param>
        /// <param name="async">如果置为true，该API将会以异步方式被调用；也就是立即返回一个session id，稍后可通过/info/get_session查询结果。默认值为false。 </param>
        /// <returns></returns>
        IIdentify IdentifyFromGroupId(string group_id, string url, ModeType mode = ModeType.NORMAL, bool async = false);
        /// <summary>
        /// 对于一个待查询的Face列表（或者对于给定的Image中所有的Face），在一个Group中查询最相似的Person。
        /// </summary>
        /// <param name="group_id">识别候选人组成的Group</param>
        /// <param name="imgByte">待识别的图片二进制</param>
        /// <param name="mode">检测模式可以是normal(默认) 或者 oneface 。在oneface模式中，检测器仅找出图片中最大的一张脸。仅当给出了url或img时，本选项有效。</param>
        /// <param name="async">如果置为true，该API将会以异步方式被调用；也就是立即返回一个session id，稍后可通过/info/get_session查询结果。默认值为false。 </param>
        /// <returns></returns>
        IIdentify IdentifyFromGroupId(string group_id, byte[] imgByte, ModeType mode = ModeType.NORMAL, bool async = false);
        /// <summary>
        /// 对于一个待查询的Face列表（或者对于给定的Image中所有的Face），在一个Group中查询最相似的Person。
        /// </summary>
        /// <param name="group_id"></param>
        /// <param name="face_ids"></param>
        /// <param name="mode"></param>
        /// <param name="async"></param>
        /// <returns></returns>
        IIdentify IdentifyFromGroupId(string group_id, string[] face_ids, ModeType mode = ModeType.NORMAL, bool async = false);

        /// <summary>
        /// 对于一个待查询的Face列表（或者对于给定的Image中所有的Face），在一个Group中查询最相似的Person。
        /// </summary>
        /// <param name="group_name"></param>
        /// <param name="url"></param>
        /// <param name="mode"></param>
        /// <param name="async"></param>
        /// <returns></returns>
        IIdentify IdentifyFromGroupName(string group_name, string url, ModeType mode = ModeType.NORMAL, bool async = false);
        /// <summary>
        /// 对于一个待查询的Face列表（或者对于给定的Image中所有的Face），在一个Group中查询最相似的Person。
        /// </summary>
        /// <param name="group_name"></param>
        /// <param name="imgByte"></param>
        /// <param name="mode"></param>
        /// <param name="async"></param>
        /// <returns></returns>
        IIdentify IdentifyFromGroupName(string group_name, byte[] imgByte, ModeType mode = ModeType.NORMAL, bool async = false);
        /// <summary>
        /// 对于一个待查询的Face列表（或者对于给定的Image中所有的Face），在一个Group中查询最相似的Person。
        /// </summary>
        /// <param name="group_name"></param>
        /// <param name="face_ids"></param>
        /// <param name="mode"></param>
        /// <param name="async"></param>
        /// <returns></returns>
        IIdentify IdentifyFromGroupName(string group_name, string[] face_ids, ModeType mode = ModeType.NORMAL, bool async = false);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="jsonStr"></param>
        /// <returns></returns>
        IIdentify IdentifyFromJsonStr(string jsonStr);
    }
    public class Face_identify:IFace_identify
    {
        private static IFace_identify instance;
        /// <summary>
        /// 单例模式
        /// </summary>
        public static IFace_identify Instance
        {
            get
            {
                if(instance==null)
                {
                    instance = new Face_identify();
                }
                return instance;
            }
        }

        
        
        private const string API_URL = "https://apicn.faceplusplus.com/v2/recognition/identify";
     

        public IIdentify IdentifyFromJsonStr(string jsonStr)
        {
            try
            {
                IIdentify identify = new Identify();
                identify.CopyObject(Json.Deserialize(jsonStr) as Dictionary<string,object> );
                return identify;
            }
            catch (Exception)
            {
                
               // throw;
            }
            return null;
        }

        public IIdentify IdentifyFromGroupId(string group_id, string url, ModeType mode = ModeType.NORMAL, bool async = false)
        {
            string modeStr = (mode == ModeType.NORMAL) ? "normal" : "oneface";
            string sendUrl = API_URL + "?api_secret=" + Facepp_config.api_secret + "&api_key=" + Facepp_config.api_key +"&group_id="+group_id+ "&url=" + url+"&mode="+modeStr+"&async="+async.ToString();
            return IdentifyFromJsonStr(HttpHelper.CreateGetHttpText(sendUrl));
        }

        public IIdentify IdentifyFromGroupId(string group_id, byte[] imgByte, ModeType mode = ModeType.NORMAL, bool async = false)
        {
            string modeStr = (mode == ModeType.NORMAL) ? "normal" : "oneface";
            IDictionary<object, object> h = new Dictionary<object, object>();
            h.Add("api_key", FacePP.Facepp_config.api_key);
            h.Add("api_secret", FacePP.Facepp_config.api_secret);
            h.Add("group_id", group_id);
            h.Add("mode", modeStr);
            h.Add("async", async);
            return IdentifyFromJsonStr(HttpHelper.CreatePostHttpText(API_URL, h, imgByte));
        }

        public IIdentify IdentifyFromGroupId(string group_id, string[] face_ids, ModeType mode = ModeType.NORMAL, bool async = false)
        {
            string modeStr = (mode == ModeType.NORMAL) ? "normal" : "oneface";
            string key_face_id = string.Join(",", face_ids);
            string sendUrl = API_URL + "?api_secret=" + Facepp_config.api_secret + "&api_key=" + Facepp_config.api_key + "&group_id=" + group_id + "&key_face_id=" +key_face_id + "&mode=" + modeStr + "&async=" + async.ToString();
            return IdentifyFromJsonStr(HttpHelper.CreateGetHttpText(sendUrl));
        }

        public IIdentify IdentifyFromGroupName(string group_name, string url, ModeType mode = ModeType.NORMAL, bool async = false)
        {
            string modeStr = (mode == ModeType.NORMAL) ? "normal" : "oneface";
            string sendUrl = API_URL + "?api_secret=" + Facepp_config.api_secret + "&api_key=" + Facepp_config.api_key + "&group_name=" + group_name + "&url=" + url + "&mode=" + modeStr + "&async=" + async.ToString();
            return IdentifyFromJsonStr(HttpHelper.CreateGetHttpText(sendUrl));
        }

        public IIdentify IdentifyFromGroupName(string group_name, byte[] imgByte, ModeType mode = ModeType.NORMAL, bool async = false)
        {
            string modeStr = (mode == ModeType.NORMAL) ? "normal" : "oneface";
            IDictionary<object, object> h = new Dictionary<object, object>();
            h.Add("api_key", FacePP.Facepp_config.api_key);
            h.Add("api_secret", FacePP.Facepp_config.api_secret);
            h.Add("group_name", group_name);
            h.Add("mode", modeStr);
            h.Add("async", async);
            return IdentifyFromJsonStr(HttpHelper.CreatePostHttpText(API_URL, h, imgByte));
        }

        public IIdentify IdentifyFromGroupName(string group_name, string[] face_ids, ModeType mode = ModeType.NORMAL, bool async = false)
        {
            string modeStr = (mode == ModeType.NORMAL) ? "normal" : "oneface";
            string key_face_id = string.Join(",", face_ids);
            string sendUrl = API_URL + "?api_secret=" + Facepp_config.api_secret + "&api_key=" + Facepp_config.api_key + "&group_name=" + group_name + "&key_face_id=" + key_face_id + "&mode=" + modeStr + "&async=" + async.ToString();
            return IdentifyFromJsonStr(HttpHelper.CreateGetHttpText(sendUrl));
        }
    }
}
